package com.upf1sh.controller;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.upf1sh.bean.FileEntity;
import com.upf1sh.service.FileService;
import com.upf1sh.utils.JwtUtils;
import com.upf1sh.utils.Result;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@RestController
@RequestMapping("/file")
//@CrossOrigin(value = "http://116.204.81.67:8001", maxAge = 1800, allowedHeaders = "*")
@CrossOrigin(origins = "*", maxAge = 3600)
public class FileController {

    @javax.annotation.Resource
    private FileService fileService;

    /**
     * UpF1sh
     * 显示下载进度条
     * 2023/6/3 15:54
     *
     * @param name
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("/downloadPro")
    @CrossOrigin
    public void downloadFile(String path, String name, HttpServletRequest request, HttpServletResponse response, AtomicBoolean cancelFlag) throws IOException {
        // 设置要下载的文件路径
        String filePath = path;

        File file = new File(filePath);
        if (file.exists()) {
            Resource resource = new FileSystemResource(file);
            long fileSize = resource.contentLength();

            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + name);
            response.setHeader(HttpHeaders.CONTENT_TYPE, "application/octet-stream");
            response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileSize));

            // 允许跨域请求
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET");
            response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION + "," + HttpHeaders.CONTENT_TYPE + "," + HttpHeaders.CONTENT_LENGTH);

            try (InputStream inputStream = resource.getInputStream(); OutputStream outputStream = response.getOutputStream()) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                long totalBytesRead = 0;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    if (cancelFlag.get()) {
                        // 前端请求取消下载
                        response.setStatus(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE.value());
                        break; // 中止下载
                    }
                    outputStream.write(buffer, 0, bytesRead);
                    totalBytesRead += bytesRead;
                    // 计算下载进度
                    int progress = (int) ((totalBytesRead * 100) / fileSize);
//                    System.out.println("Download progress: " + progress + "%");
                }
                outputStream.flush();
//                System.out.println("Download complete");
            } catch (IOException e) {
                System.err.println("Error occurred during download: " + e.getMessage());
                response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            }
        } else {
            response.setStatus(HttpStatus.NOT_FOUND.value());
        }
    }

    @RequestMapping("/upload")
    public void uploadFile(MultipartFile file, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        String username = JwtUtils.getClaimsByToken(token).getSubject();
        String status = fileService.upload(file, username);
    }

    /**
     * 接收快照
     *
     * @param file
     * @return
     */
    @PostMapping("/uploadSnapshot")
    public Result uploadSnapshot(MultipartFile file) {
        return Result.ok().data("path", fileService.uploadSnapshot(file));
    }

    /**
     * 其他课题外部使用api
     * 2023/7/4 20:20
     *
     * @param file
     * @param belong
     */

    @RequestMapping("/uploadFile")
    public void uploadFileByUrl(@RequestParam("file") MultipartFile file, @RequestParam("belong") String belong) {

        String status = fileService.upload(file, belong);
//        if (status.length() == 6)
//            return Result.error().data("error", "文件已存在！");
//        else if (status.length() == 5)
//            return Result.ok().data("success", status);
//        else return Result.error().data("error", "出错了！");


    }

    @PostMapping("/getAllFile")
    private Result getAllFile() {
        String path = ("/data/file/");
        File[] array = fileService.orderByDate(path);
        return Result.ok().data("filelist", array);
    }

    /**
     * 普通查询
     * 2023/4/18 18:06
     *
     * @return
     */
    @PostMapping("/getAllFileInDB")
    private Result getAllFileInDB() {
        List<FileEntity> files = fileService.findAllInDB();
        return Result.ok().data("files", files);
    }


    /**
     * 删除文件
     * 2023/4/18 10:17
     *
     * @param path
     * @return
     */
    @PostMapping("/deleteFile")
    public Result deleteFile(String path) {
        if (fileService.delete(path) == 1)
            return Result.ok().data("success", "删除成功！");
        else if (fileService.delete(path) == 2)
            return Result.error().data("error", "删除失败！");

        else if (fileService.delete(path) == 3)
            return Result.error().data("error", "无此权限！");

        return Result.error().data("error", "文件不存在！");
//        return fileService.delete(path) && fileService.deleteFile_db(path) ? Result.ok() : Result.error();
    }

    /**
     * 分页查询
     * UpF1sh
     * 2023/4/18
     * 17:43
     *
     * @param pageNum
     * @return
     */
    @PostMapping("/getAllFileInDBByPage")
    public Result getAll(String belong, @RequestParam(defaultValue = "1") int pageNum) {
//      分页对象，传入当前页码及每页的数量
        Page<FileEntity> page = new Page(pageNum, 10);
        Page<FileEntity> files = fileService.findAllInDBByPage(page, belong);
        return Result.ok().data("items", files);
    }

    /**
     * 上传者
     * UF
     * 2023/4/20 21:46
     *
     * @return
     */
    @RequestMapping("/getOwner")
    public Result GetOwner() {
//        System.out.println(response.getContentType());
        return Result.ok().data("owner", fileService.GetOwner());
    }


    /**
     * 上传文件夹
     * UpF1sh
     * 2023/4/22 21:52
     *
     * @param fileFolder
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/upload_folder")
    @CrossOrigin
    public Result uploadSoundCode(@RequestParam("files") List<MultipartFile> fileFolder, HttpServletRequest request) throws IOException {
        String token = request.getHeader("Authorization");
        String username = JwtUtils.getClaimsByToken(token).getSubject();

        boolean re = fileService.uploadSoundCode(fileFolder, username);
        if (re)
            return Result.ok();
        return Result.error();
//        return Result.ok().data("url", soundCodeUrl);
    }

//    @Value("${data.dataDir}")
//    String dataDir;

    /**
     * download
     * 2023/5/3 16:01
     *
     * @param
     * @param
     * @throws IOException
     */
    @CrossOrigin(origins = "*", maxAge = 3600)
    @RequestMapping("/down")
    public void down(String path, String name, HttpServletResponse response) throws IOException {
        File file = new File(path);
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
        response.setContentType("application/octet-stream");
        os.write(FileUtil.readBytes(file));
        os.flush();
        os.close();
    }


    @CrossOrigin(origins = "*", maxAge = 3600)
    @RequestMapping("/downUrl")
    public Result downUrl(String path, String name, HttpServletResponse response) throws IOException {
//        File file = new File(path);
        System.out.println(path);
        System.out.println(name);
//        ServletOutputStream os = response.getOutputStream();
//        response.addHeader("Content-Disposition", "attachment;");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
        response.setContentType("application/octet-stream");
//        os.write(FileUtil.readBytes(file));
//        os.flush();
//        os.close();
        String url = "http://116.204.81.67:8848" + path;
        return Result.ok().data("url", url);
    }

}